package org.ewaf.framework.lucene.writer;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;


public class BatchIndexWriter {

	private LinkedBlockingQueue<Document> queue = new LinkedBlockingQueue<Document>();

	private volatile boolean stop = false;

	private Analyzer analyzer;

	public Analyzer getAnalyzer() {
		return analyzer;
	}

	public void setAnalyzer(Analyzer analyzer) {
		this.analyzer = analyzer;
	}

	private IndexWriter diskWriter;
	private IndexWriter ramWriter;
	
	private RAMDirectory  ramDir;

	private long gmtIndex;
	private String indexDir;

	public String getIndexDir() {
		return indexDir;
	}

	public void setIndexDir(String indexDir) {
		this.indexDir = indexDir;
	}
	File dir ;
	public void init() {

		gmtIndex = System.currentTimeMillis();

		dir = new File(indexDir);
		if (!dir.isDirectory()) {
			throw new IllegalArgumentException();
		}
		
		ramDir=new RAMDirectory();

		try {
			diskWriter = new IndexWriter(FSDirectory.open(dir), analyzer, true,
					IndexWriter.MaxFieldLength.LIMITED);

			ramWriter = new IndexWriter(ramDir, analyzer, true,
					IndexWriter.MaxFieldLength.LIMITED);
		} catch (CorruptIndexException e) {
			throw new IllegalArgumentException(e);
		} catch (LockObtainFailedException e) {
			throw new IllegalArgumentException(e);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}

		new Worker().start();
	}

	public void add(Document doc) {

		try {
			queue.offer(doc, 1, TimeUnit.SECONDS);
		} catch (InterruptedException ignore) {

		}

	}

	private class Worker extends Thread {

		@Override
		public void run() {

			while (!stop) {

				Document doc;
				try {
					doc = queue.poll(1, TimeUnit.SECONDS);
				} catch (InterruptedException e) {
					continue;
				}

				if (doc == null) {
					continue;
				}

				try {
					ramWriter.addDocument(doc);
					
				    

					if (System.currentTimeMillis() - gmtIndex > 1000
							|| ramWriter.ramSizeInBytes() > 256 * 1024) {
						gmtIndex = System.currentTimeMillis();


						
						diskWriter.addIndexesNoOptimize(new Directory[] { ramDir
										});

						ramWriter.close();
						
						
						ramWriter = new IndexWriter(ramDir,
								analyzer, true,
								IndexWriter.MaxFieldLength.LIMITED);
						
						diskWriter.commit();
						
				/*		diskWriter.close();
						
						diskWriter = new IndexWriter(FSDirectory.open(dir),
								analyzer, true,
								IndexWriter.MaxFieldLength.LIMITED);*/

					}
				} catch (CorruptIndexException ignore) {

				} catch (IOException ignore) {

				}

			}

		}

	}

}
